package org.jeecg.modules.power.device.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.mchange.lang.IntegerUtils;
import io.swagger.models.auth.In;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang.StringUtils;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.exception.ChechDataAuthException;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.modules.app.util.NumberArithmeticUtils;
import org.jeecg.modules.app.v1.device.entity.*;
import org.jeecg.modules.app.v1.shop.entity.ApiAddShopEntity;
import org.jeecg.modules.app.v1.util.Const;
import org.jeecg.modules.power.config.service.IYlCheckConfigService;
import org.jeecg.modules.power.device.entity.*;
import org.jeecg.modules.power.device.mapper.YlDeviceRecordsMapper;
import org.jeecg.modules.power.device.service.*;
import org.jeecg.modules.power.group.entity.GroupUser;
import org.jeecg.modules.power.group.service.IYlGroupService;
import org.jeecg.modules.power.shop.entity.YlShop;
import org.jeecg.modules.power.shop.service.IYlShopService;
import org.jeecg.modules.power.statistics.entity.YlWeaningShopRecord;
import org.jeecg.modules.power.statistics.service.IYlWeaningShopRecordService;
import org.jeecg.modules.system.entity.SysUser;
import org.jeecg.modules.system.service.ISysUserService;
import org.springframework.beans.BeanUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.transaction.annotation.Transactional;

import java.awt.geom.QuadCurve2D;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.*;

/**
 * @Description: 设备变动记录表
 * @Author: jeecg-boot
 * @Date:   2024-07-17
 * @Version: V1.0
 */
@Service
@RequiredArgsConstructor
public class YlDeviceRecordsServiceImpl extends ServiceImpl<YlDeviceRecordsMapper, YlDeviceRecords> implements IYlDeviceRecordsService {

    private final IYlDeviceService deviceService;
    private final IYlWarehouseService warehouseService;
    private final IYlWarehouseRecordsService warehouseRecordsService;
    private final IYlGroupService groupService;
    private final IYlCheckConfigService configService;
    private final IYlDeviceCategoryService deviceCategoryService;
    private final IYlWeaningShopRecordService weaningShopRecordService;
    private final RedisTemplate redisTemplate;

    /**-----------------------------------------后台使用----------------------------------------------------------------------------------*/
    //region 后台相关的方法
    /**
     * 后台审核设备转移
     * @param records
     */
    public void check(YlDeviceRecords records){
        /**
         * 设备转移
         */
        if(Objects.equals(records.getTransferType(),Const.transferType_6))this.checkTransfer(records);
        if(Objects.equals(records.getTransferType(),Const.transferType_8))this.stock(records);
        if(Objects.equals(records.getTransferType(),Const.transferType_5))this.unbind(records);
    }


    /**
     * 后台审核设备转移
     * @param records
     */
    public void checkTransfer(YlDeviceRecords records){
        if(records.getTransferStatus()==2){
            /**
             * 直接转移绑定
             */
            deviceService.bindUser(records.getDeviceId(),records.getReceiveId());
        }
        String businessId = String.format(Const.device_business_id_C,records.getId());
        deviceService.unlock(records.getDeviceId(),businessId);
        this.updateById(records);
    }

    /**
     * 后台管理员进行调拨
     */
    public void transfer(YlDevice device){

        String businssId = device.getKey();
        String businssName = device.getLabel();
        Integer type = device.getType(); /** type : {@link Const.deviceStatus_1} */
        YlDeviceRecords deviceRecords = new YlDeviceRecords();
        deviceRecords.setDeviceId(device.getId());
        deviceRecords.setDeviceMac(device.getDeviceMac());

        deviceRecords.setTransferId(device.getBusinessId());
        deviceRecords.setTransferName(device.getLocation());
        deviceRecords.setTransferRemark(Const.DBO);
        Date date = new Date();
        deviceRecords.setTransferTime(date);
        deviceRecords.setTransferStatus(Const.transferStatus_2);
        deviceRecords.setReceiveId(businssId);
        deviceRecords.setReceiveName(businssName);
        String id = NumberArithmeticUtils.getTimestamp();
        deviceRecords.setId(id);
        String transferNumber = String.format("%s_%s",Const.transfer_number_DB,id);
        deviceRecords.setTransferNumber(transferNumber);
        deviceRecords.setCreateTime(date);
        deviceRecords.setTransferType(Const.transferType_7);
        boolean ds = this.save(deviceRecords);
        /**
         * 变更设备信息
         */
        if(ds)deviceService.bind(device.getId(), businssId,type);
    }

    /**
     * 后台审核报修退库
     * @param records
     */
    public void stock(YlDeviceRecords records){
        /**
         * 1、更新设备所属信息
         * 2、更新审核状态
         */
        if(records.getTransferStatus()==2){
            /**
             * 直接转移绑定
             */
            deviceService.bind(records.getDeviceId(),records.getReceiveId(),Const.deviceStatus_1);
        }
        String businessId = String.format(Const.device_business_id_C,records.getId());
        deviceService.unlock(records.getDeviceId(),businessId);
        this.updateById(records);
    }
    /**
     * 后台审核报修退库
     * @param records
     */
    public void unbind(YlDeviceRecords records){
        /**
         * 1、更新设备所属信息
         * 2、更新审核状态
         */
        if(records.getTransferStatus()==2){
            /**
             * 直接转移绑定
             */
            deviceService.bind(records.getDeviceId(),records.getReceiveId(),Const.deviceStatus_2);

            GroupUser user = groupService.getUserGroup(records.getReceiveId());
            /**
             * 解绑记录统计（用于首页撤机门店统计）
             */
            this.saveRecords(records,user);

            /**
             * 记录解绑，判定门店是否已无设备
             */
            ZoneId defaultZoneId = ZoneId.systemDefault();
            LocalDateTime dateTime = LocalDateTime.ofInstant(records.getCreateTime().toInstant(), defaultZoneId).plusDays(7);
            String unbindTime = dateTime.toString();
            String unbindDate = dateTime.toLocalDate().toString();
            this.saveEmptyShopRecords(records.getTransferId(),unbindTime,unbindDate);

        }
        String businessId = String.format(Const.device_business_id_D,records.getId());
        deviceService.unlock(records.getDeviceId(),businessId);
        this.updateById(records);
    }

    /**
     * 判定当前门店下是否还有绑定设备，没有直接保存无设备门店记录，用于7天无设备门店自动进入公海业务
     * @param shopId
     * @param unbindTime
     * @param unbindDate
     */
    @Override
    public void saveEmptyShopRecords(String shopId, String unbindTime, String unbindDate) {
        /**
         * 判定门店下是否还有设备未解绑
         */
        int count = this.countShopDevice(shopId);
        if(count==0)baseMapper.saveEmptyShopRecords(shopId, unbindTime, unbindDate);
    }

    /**
     * 门店绑定设备，删除无设备门店记录，兼顾如果记录已经进入redis队列，需要同时处理
     * @param shopId
     */
    @Override
    public void deleteEmptyShop(String shopId) {
        baseMapper.deleteEmptyShop(shopId);
        String expireKey = Const.getEmptyShopKey(shopId);
        if(redisTemplate.hasKey(expireKey))redisTemplate.delete(expireKey);
    }

    @Override
    public List<YlEmptyShopRecords> emptyShopList() {
        return baseMapper.emptyShopList();
    }

    //endregion
    /**-----------------------------------------后台使用----------------------------------------------------------------------------------*/



    /**-----------------------------------------接口使用----------------------------------------------------------------------------------*/
    //region 接口相关的方法

    /**
     * 资产一览-故障设备列表
     * @param page
     * @param categoryId
     * @param mac
     * @param groupId 权限数据查询
     * @param flag {@link org.jeecg.modules.app.v1.util.Const.sourceType_1}
     * @param status {@link org.jeecg.modules.app.v1.util.Const.transferStatus_1}
     * @return
     */
    @Override
    public IPage<ApiFaultDeviceEntity> faultDeviceList(Page<ApiFaultDeviceEntity> page, String mac, String categoryId, String flag, String groupId,String sourceType,String status) {
        return baseMapper.faultDeviceList(page, mac, categoryId, flag, groupId,sourceType,status);
    }


    /**
     * 门店下设备解绑绑定记录
     * @param page
     * @param shopId
     * @param beginTime
     * @param endTime
     * @return
     */
    @Override
    public IPage<ApiBindDeviceEntity> shopBindDevice(Page<ApiBindDeviceEntity> page, String shopId, String beginTime, String endTime) {
        String bTime = oConvertUtils.isNotEmpty(beginTime)?String.format("%sT%s",beginTime,Const.TIME_000000):"";
        String eTime = oConvertUtils.isNotEmpty(endTime)?String.format("%sT%s",endTime,Const.TIME_235959):"";
        return baseMapper.shopBindDevice(page, shopId, bTime, eTime);
    }
    /**
     * 校验设备是否可退库
     * @param deviceNo
     * @param bdId
     * @return
     */
    public JSONObject getDevice(String deviceNo, String bdId){
        JSONObject result = new JSONObject();
        QueryWrapper<YlDevice> queryWrapper = new QueryWrapper<>();
        queryWrapper
                .eq("device_mac",deviceNo)
                .last("limit 1");
        YlDevice device = deviceService.getOne( queryWrapper);
        if(oConvertUtils.isEmpty(device))return null;
        result.put("mac",device.getDeviceMac());
        YlDeviceCategory category = deviceCategoryService.getById(device.getDeviceCategory());
        result.put("category",category.getCategoryName());
        result.put("available",2);
        result.put("remark","只能对位置在本人的设备进行退库申请");


        /**
         * 设备有无故障
         */
        if(device.getIsFault()==2){
            result.put("available",2);
            result.put("remark","设备存在故障");
        }
        /**
         * 设备状态不是1 ，处于业务审核过程中，不能操作
         */
        if(!Objects.equals(device.getDeviceLock(),Const.deviceLock_1)){
            result.put("available",2);
            String prefix = device.getDeviceLock().substring(0,2)+"%s";
            String businessId = device.getDeviceLock().substring(2);
            YlDeviceRecords deviceRecords = this.getById(businessId);
            String msg = "";
            /**
             * 未查询到是设备操作记录
             */
            if(oConvertUtils.isEmpty(deviceRecords))
                msg = String.format("设备操作记录状态异常，未查询到当前的操作记录（操作业务码：%s）",device.getDeviceLock());
            /**
             * A设备绑定门店等待审核
             */
            if(Objects.equals(prefix,Const.device_business_id_A))
                 msg = String.format("设备处于绑定门店（%s）审核中,操作人：%s",deviceRecords.getReceiveName(),deviceRecords.getCreateBy());
            /**
             * B设备退库等待审核
             */
            if(Objects.equals(prefix,Const.device_business_id_B))
                 msg = String.format("设备处于退库（%s）审核中,操作人：%s",deviceRecords.getReceiveName(),deviceRecords.getCreateBy());
            /**
             * C设备资产转移待审核
             */
            if(Objects.equals(prefix,Const.device_business_id_C))
                 msg = String.format("设备处于转移BD（%s）审核中,操作人：%s",deviceRecords.getReceiveName(),deviceRecords.getCreateBy());

            result.put("remark",msg);
            return result;
        }
        if(Objects.equals(device.getDeviceStatus(),Const.deviceStatus_2)){
            GroupUser groupUser = groupService.getUserGroup(device.getBusinessId());
            result.put("location",groupUser.getUserInfo());
            if(Objects.equals(bdId,groupUser.getUserId())){
                result.put("available",1);
                result.put("remark","");
            }
        }else if(Objects.equals(device.getDeviceStatus(),Const.deviceStatus_3)){
            result.put("location","门店");
        } else if (Objects.equals(device.getDeviceStatus(),Const.deviceStatus_1)) {
            result.put("location","仓库");
        }else {
            result.put("location","未知状态");
        }

        return result;
    }

    /**
     * 校验设备是否可绑定
     * @param deviceMac
     * @return
     */
    public JSONObject getNewDevice(String deviceMac, String bdId){
        JSONObject result = new JSONObject();
        QueryWrapper<YlDevice> queryWrapper = new QueryWrapper<>();
        queryWrapper
                .eq("device_mac",deviceMac)
                .last("limit 1");
        YlDevice device = deviceService.getOne( queryWrapper);
        if(oConvertUtils.isEmpty(device))return null;
        result.put("mac",device.getDeviceMac());
        YlDeviceCategory category = deviceCategoryService.getById(device.getDeviceCategory());
        result.put("category",category.getCategoryName());
        result.put("available",2);
        result.put("deviceId",device.getId());
        result.put("remark","只能对位置在本人或者仓库的设备进行绑定");

        /**
         * 设备有无故障
         */
        if(device.getIsFault()==2){
            result.put("available",2);
            result.put("remark","设备存在故障");
        }
        /**
         * 设备状态不是1 ，处于业务审核过程中，不能操作
         */
        if(!Objects.equals(device.getDeviceLock(),Const.deviceLock_1)){
            result.put("available",2);
            String prefix = device.getBusinessId().substring(0,2)+"%s";
            String businessId = device.getBusinessId().substring(2);
            YlDeviceRecords deviceRecords = this.getById(businessId);
            String msg = "";
            /**
             * 未查询到是设备操作记录
             */
            if(oConvertUtils.isEmpty(deviceRecords))
                msg = String.format("设备操作记录状态异常，未查询到当前的操作记录（操作业务码：%s）",device.getBusinessId());
            /**
             * A设备绑定门店等待审核
             */
            if(Objects.equals(prefix,Const.device_business_id_A))
                msg = String.format("设备处于绑定门店（%s）审核中,操作人：%s",deviceRecords.getReceiveName(),deviceRecords.getCreateBy());
            /**
             * B设备退库等待审核
             */
            if(Objects.equals(prefix,Const.device_business_id_B))
                msg = String.format("设备处于退库（%s）审核中,操作人：%s",deviceRecords.getReceiveName(),deviceRecords.getCreateBy());
            /**
             * C设备资产转移待审核
             */
            if(Objects.equals(prefix,Const.device_business_id_C))
                msg = String.format("设备处于转移BD（%s）审核中,操作人：%s",deviceRecords.getReceiveName(),deviceRecords.getCreateBy());

            result.put("remark",msg);
            return result;
        }

        if(Objects.equals(device.getDeviceStatus(),Const.deviceStatus_2)){
            GroupUser groupUser = groupService.getUserGroup(device.getBusinessId());
            result.put("location",groupUser.getUserInfo());
            if(Objects.equals(bdId,groupUser.getUserId())){
                result.put("available",1);
                result.put("type",Const.deviceStatus_2);
                result.put("id",groupUser.getUserId());
                result.put("remark","");
            }
        }else if(Objects.equals(device.getDeviceStatus(),Const.deviceStatus_3)){
            result.put("location","门店");
        } else if (Objects.equals(device.getDeviceStatus(),Const.deviceStatus_1)) {
            result.put("available",1);
            YlWarehouse warehouse = warehouseService.getById(device.getBusinessId());
            String houseName = String.format("仓库 | %s",warehouse.getHouseName());
            result.put("location",houseName);
            result.put("id",warehouse.getId());
            result.put("type",Const.deviceStatus_1);
            result.put("remark","");
        }else {
            result.put("location","未知状态");
        }
        if(device.getIsFault()==2){
            result.put("available",2);
            result.put("remark","设备存在故障");
        }
        return result;
    }


    /**
     * 设备退库申请记录（包含异常退库）
     * @param page
     * @param transferNumber
     * @param beginTime
     * @param endTime
     * @param deviceCategory
     * @param transferType
     * @return
     */
    public List<ApiStockDeviceRecordEntity> getDeviceRecords(Page<ApiStockDeviceRecordEntity> page,
                                                             String transferId,
                                                             String transferNumber,
                                                             String beginTime,
                                                             String endTime,
                                                          String deviceCategory, String transferType){
        String bTime = oConvertUtils.isNotEmpty(beginTime)?String.format("%sT%s",beginTime,Const.TIME_000000):"";
        String eTime = oConvertUtils.isNotEmpty(endTime)?String.format("%sT%s",endTime,Const.TIME_235959):"";
        IPage<ApiStockDeviceRecordEntity> pageList = baseMapper.stockDeviceRecords(page, transferId,transferNumber, bTime, eTime, deviceCategory, transferType);
        return pageList.getRecords();
    }

    /**
     * 新增门店，针对需要审核的情况的，对设备加锁，防止其他操作。
     * @param deviceList
     * @param lockId
     */
    @Transactional
    public void lockDevice(List<ApiAddShopEntity.DeviceInfo> deviceList,String lockId){

        for(ApiAddShopEntity.DeviceInfo deviceInfo:deviceList){
            boolean res = deviceService.lock(deviceInfo.getId(),lockId);
            if(!res)throw new ChechDataAuthException("设备（mac:"+deviceInfo.getMac()+")状态异常。");
        }

    }
    /**
     * 新增门店，针对需要审核的情况的，对设备加锁，防止其他操作。
     * @param deviceList
     * @param lockId
     */
    @Transactional
    public void unlockDevice(List<ApiAddShopEntity.DeviceInfo> deviceList,String lockId){
        for(ApiAddShopEntity.DeviceInfo deviceInfo:deviceList){
            boolean res = deviceService.unlock(deviceInfo.getId(),lockId);
            if(!res)throw new ChechDataAuthException("设备（mac:"+deviceInfo.getMac()+")状态异常。");
        }

    }


    @Override
    public IPage<ApiUnbindDeviceEntity> unbindDeviceList(Page<ApiUnbindDeviceEntity> page, String transferStatus, String transferNumber,String receiveId) {
        return baseMapper.unbindDeviceList(page, transferStatus, transferNumber,receiveId,Const.transferType_5);
    }

    @Override
    public IPage<ApiBindDeviceEntity> bindDeviceList(Page<ApiBindDeviceEntity> page, String deviceId) {
        return baseMapper.bindDeviceList(page, deviceId);
    }
    /**
     * bd间资产转移列表
     * @param page
     * @param transferId
     * @param receiveId
     * @param transferNumber
     * @return
     */
    @Override
    public IPage<ApiBindDeviceEntity> bdDeviceList(Page<ApiBindDeviceEntity> page, String transferId, String receiveId,String transferNumber){
        return baseMapper.bdDeviceList(page, transferId, receiveId, transferNumber);
    }
    /**
     * 新增设备入库
     * @param device
     */
    @Transactional
    public void saveDevice(YlDevice device){

        YlWarehouse warehouse = warehouseService.getById(device.getBusinessId());
        if(oConvertUtils.isEmpty(warehouse))throw new ChechDataAuthException("入库失败（未查询到仓库信息）");

        boolean de = deviceService.save(device);
        if(!de)throw new ChechDataAuthException("入库失败（设备信息保存失败）");

        /**
         * 出入库记录
         */
        boolean res = warehouseRecordsService.saveDeviceRecords(device,warehouse);
        if(!res)throw new ChechDataAuthException("入库失败（设备入库记录保存失败）");

        YlDeviceRecords deviceRecords = new YlDeviceRecords();
        deviceRecords.setDeviceName(device.getDeviceName());
        deviceRecords.setDeviceId(device.getId());
        deviceRecords.setDeviceMac(device.getDeviceMac());
        deviceRecords.setTransferName(Const.RK);
        deviceRecords.setTransferRemark(Const.RK);
        deviceRecords.setTransferTime(device.getCreateTime());
        deviceRecords.setTransferStatus(Const.transferStatus_2);
        deviceRecords.setTransferId(Const.RK_ID);
        deviceRecords.setReceiveId(device.getBusinessId());
        deviceRecords.setReceiveName(warehouse.getHouseName());
        String id = NumberArithmeticUtils.getTimestamp();
        deviceRecords.setId(id);
        String transferNumber = String.format("%s_%s",Const.transfer_number_RK,id);
        deviceRecords.setTransferNumber(transferNumber);
        deviceRecords.setCreateTime(device.getCreateTime());
        deviceRecords.setTransferType(Const.transferType_3);
        boolean ds = this.save(deviceRecords);
        if(!ds)throw new ChechDataAuthException("入库失败（设备流转记录保存失败）");
    }

    /**
     * 报修退库
     * @param deviceMac 多个设备以,隔开
     * @param storeId
     * @param bd
     */
    @Transactional
    public void stock(String deviceMac,String storeId, SysUser bd,String type){
        YlDeviceRecords records = new YlDeviceRecords();
        records.setReceiveId(storeId);
        YlWarehouse warehouse = warehouseService.getById(storeId);
        records.setReceiveName(warehouse.getHouseName());
        records.setTransferId(bd.getId());
        GroupUser groupUser = deviceService.getGroupUser(bd.getId());
        records.setTransferName(groupUser.getUserInfo());
        records.setTransferTime(new Date());
        records.setTransferType(Const.transferType_8);
        records.setCreateBy(groupUser.getUserInfo());
        records.setTransferRemark(type);
        String deviceMacs[] = deviceMac.split(",");
        QueryWrapper<YlDevice> deviceQueryWrapper = new QueryWrapper<>();
        /**
         * 再筛选你一遍，防止传错了
         */
        deviceQueryWrapper
                .eq("device_status",Const.deviceStatus_2)
                .eq("business_id",bd.getId())
                .in("device_mac",deviceMacs);
        List<YlDevice> deviceList = deviceService.list(deviceQueryWrapper);
        List<YlDeviceRecords> recordsList = new ArrayList<>();

        /**
         * 保修退库自动审核
         * check 1 需要审核2直接通过不审核
         */
        Integer check = configService.getCheckRepair()==1?2:1; //1自动审核2手动审核

        for(YlDevice device:deviceList){
            YlDeviceRecords deviceRecords = new YlDeviceRecords();
            BeanUtils.copyProperties(records,deviceRecords);
            String id = NumberArithmeticUtils.getTimestamp();
            deviceRecords.setId(id);
            String transferNumber = String.format("%s_%s",Const.transfer_number_BX,id);
            deviceRecords.setTransferNumber(transferNumber);
            deviceRecords.setDeviceMac(device.getDeviceMac());
            deviceRecords.setDeviceId(device.getId());
            deviceRecords.setDeviceName(device.getDeviceName());
            deviceRecords.setTransferStatus(check);
            /**
             * 设备状态1仓库2BD3门店9其他
             */
            deviceRecords.setSourceType(device.getDeviceStatus());

            if(check==2){
                recordsList.add(deviceRecords);
                /**设备状态1仓库2BD3门店9其他*/
                device.setDeviceStatus(Const.deviceStatus_1);
                device.setBusinessId(storeId);
                device.setIsFault(Const.isFault_2);
            }else{
                deviceRecords.setIsCheck(Const.isCheck_1);
                String businessId = String.format(Const.device_business_id_B,id);
                if(deviceService.lock(device.getId(),businessId))recordsList.add(deviceRecords);
            }
        }
        this.saveBatch(recordsList);
        /**
         * 自动审核直接更新设备状态
         */
        if(check==2)deviceService.updateBatchById(deviceList);
    }

    /**
     * 退库申请
     * @param deviceMac 多个设备以,隔开
     * @param storeId
     * @param bd
     */
    @Transactional
    public void storage(String deviceMac,String storeId, SysUser bd,String type){
        YlDeviceRecords records = new YlDeviceRecords();
        records.setReceiveId(storeId);
        YlWarehouse warehouse = warehouseService.getById(storeId);
        records.setReceiveName(warehouse.getHouseName());
        records.setTransferId(bd.getId());
        GroupUser groupUser = deviceService.getGroupUser(bd.getId());
        records.setTransferName(groupUser.getUserInfo());
        records.setTransferTime(new Date());
        records.setTransferType(Const.transferType_2);
        records.setCreateBy(groupUser.getUserInfo());
        records.setTransferRemark(type);
        String deviceMacs[] = deviceMac.split(",");
        QueryWrapper<YlDevice> deviceQueryWrapper = new QueryWrapper<>();
        /**
         * 再筛选你一遍，防止传错了
         */
        deviceQueryWrapper
                .eq("device_status",Const.deviceStatus_2)
                .eq("business_id",bd.getId())
                .in("device_mac",deviceMacs);
        List<YlDevice> deviceList = deviceService.list(deviceQueryWrapper);
        List<YlDeviceRecords> recordsList = new ArrayList<>();

        /**
         * check 1 需要审核2直接通过不审核
         */
        Integer check = configService.getStockReturn()==1?2:1; //1自动审核2手动审核

        for(YlDevice device:deviceList){
            YlDeviceRecords deviceRecords = new YlDeviceRecords();
            BeanUtils.copyProperties(records,deviceRecords);
            String id = NumberArithmeticUtils.getTimestamp();
            deviceRecords.setId(id);
            String transferNumber = String.format("%s_%s",Const.transfer_number_TK,id);
            deviceRecords.setTransferNumber(transferNumber);
            deviceRecords.setDeviceMac(device.getDeviceMac());
            deviceRecords.setDeviceId(device.getId());
            deviceRecords.setDeviceName(device.getDeviceName());
            deviceRecords.setTransferStatus(check);

            if(check==2){
                recordsList.add(deviceRecords);
                /**设备状态1仓库2BD3门店9其他*/
                device.setDeviceStatus(Const.deviceStatus_1);
                device.setBusinessId(storeId);
            }else{
                deviceRecords.setIsCheck(Const.isCheck_1);
                String businessId = String.format(Const.device_business_id_B,id);
                if(deviceService.lock(device.getId(),businessId))recordsList.add(deviceRecords);
            }
        }
        this.saveBatch(recordsList);
        /**
         * 自动审核直接更新设备状态
         */
        if(check==2)deviceService.updateBatchById(deviceList);
    }

    /**
     * 资产转移
     * @param deviceMac 多个设备以,隔开
     * @param userBd 接收方bdId
     * @param bd 转出方bd
     */
    public void transfer(String deviceMac,GroupUser userBd, GroupUser bd){
        YlDeviceRecords records = new YlDeviceRecords();
        records.setReceiveId(userBd.getUserId());
        records.setReceiveName(userBd.getUserInfo());
        records.setTransferId(bd.getUserId());
        records.setTransferName(bd.getUserInfo());
        records.setTransferTime(new Date());
        records.setTransferType(Const.transferType_6);
        records.setCreateBy(bd.getUserInfo());
        String deviceMacs[] = deviceMac.split(",");
        QueryWrapper<YlDevice> deviceQueryWrapper = new QueryWrapper<>();
        /**
         * 再筛选你一遍，防止传错了
         */
        deviceQueryWrapper
                .eq("device_status",Const.deviceStatus_2)
                .eq("business_id",bd.getUserId())
                .in("device_mac",deviceMacs);
        List<YlDevice> deviceList = deviceService.list(deviceQueryWrapper);
        List<YlDeviceRecords> recordsList = new ArrayList<>();
        /**
         * check 1 需要审核2直接通过不审核
         */
        Integer check = configService.getCheckDevice()==1?2:1; //1自动审核2手动审核

        for(YlDevice device:deviceList){
            YlDeviceRecords deviceRecords = new YlDeviceRecords();
            BeanUtils.copyProperties(records,deviceRecords);
            String id = NumberArithmeticUtils.getTimestamp();
            deviceRecords.setId(id);
            String transferNumber = String.format("%s_%s",Const.transfer_number_ZY,id);
            deviceRecords.setTransferNumber(transferNumber);
            deviceRecords.setDeviceMac(device.getDeviceMac());
            deviceRecords.setDeviceId(device.getId());
            deviceRecords.setDeviceName(device.getDeviceName());

            deviceRecords.setTransferStatus(check);

            /***
             * 处理设备
             * 1、如果直接自动审核直接进行转移
             *   如果需要审核，则先锁定设备
             */
            if(check==2){
                /**
                 * 直接转移绑定
                 */
                deviceService.bindUser(device.getId(),userBd.getUserId());
            }else {
                deviceRecords.setIsCheck(Const.isCheck_1);
                String businessId = String.format(Const.device_business_id_C,id);
                if(deviceService.lock(device.getId(),businessId))recordsList.add(deviceRecords);
            }
        }
        this.saveBatch(recordsList);
    }

    /**
     * 资产转移确认
     * @param id 多个设备以,隔开
     * @param status 是否接收 2接收3拒绝
     * @param remark 不接收理由
     */
    @Transactional
    public void confirm(String id, Integer status, String remark){
        YlDeviceRecords records = this.getById(id);
        records.setTransferStatus(status);
        records.setTransferRemark(remark);
        if(deviceService.unlock(records.getDeviceId(),records.getId()))this.updateById(records);
    }

    /**
     * 设备解绑申请单
     * @param page
     * @param status
     * @return
     */
    public IPage<YlDeviceRecords> getUnbindList(Page<YlDeviceRecords> page,
                                                Integer status,
                                                String bdId,
                                                String deviceMac,
                                                String transferNumber){
        QueryWrapper<YlDeviceRecords> recordsQueryWrapper = new QueryWrapper<>();
        recordsQueryWrapper
                .select("transfer_number,transfer_id,transfer_name,transfer_status,receive_id,receive_name,transfer_time")
                .eq(!Objects.isNull(status),"transfer_status",status)
                .eq("receive_id",bdId)
                .eq(StringUtils.isNotBlank(transferNumber),"transfer_number",transferNumber)
                .eq(StringUtils.isNotBlank(deviceMac),"device_mac",deviceMac)
                .orderByDesc("create_time")
                ;
       return this.page(page,recordsQueryWrapper);
    }

    /**
     * 解绑，设备由 门店->BD
     * 转出方为门店，接收方为BD
     * @param deviceSn
     * @param bd
     */
    @Transactional
    public void unbind(String deviceSn, SysUser bd,YlShop shop){
        YlDeviceRecords records = new YlDeviceRecords();
        String id = NumberArithmeticUtils.getTimestamp();
        records.setId(id);
        String transferNumber = String.format("%s_%s",Const.transfer_number_JB,id);
        records.setTransferNumber(transferNumber);
        records.setReceiveId(bd.getId());
        GroupUser user = groupService.getUserGroup(bd.getId());
        records.setReceiveName(user.getUserInfo());
        records.setTransferTime(new Date());
        records.setTransferType(Const.transferType_5); //解绑
        YlDevice device = deviceService.getDeviceByNo(deviceSn);
        if(oConvertUtils.isEmpty(device))throw new ChechDataAuthException("解绑失败，未查询到设备信息，请稍后再试。");
        if(oConvertUtils.isEmpty(shop))throw new ChechDataAuthException("解绑失败，门店信息有误，请稍后再试。");
        if(!Objects.equals(shop.getBdId(),bd.getId()))throw new ChechDataAuthException("解绑失败，不能解绑他人门店设备。");
        records.setTransferName(shop.getShopName());
        records.setTransferId(shop.getId());
        records.setDeviceId(device.getId());
        records.setDeviceMac(device.getDeviceMac());
        records.setDeviceName(device.getDeviceName());
        records.setCreateBy(user.getUserInfo());
        records.setCreateTime(new Date());

        /**
         * check 1 需要审核2直接通过不审核
         */
        Integer check = configService.getCheckUnbind()==1?2:1; //1自动审核2手动审核
        records.setTransferStatus(check);
        /***
         * 处理设备
         * 1、如果直接自动审核直接进行转移
         *   如果需要审核，则先锁定设备
         */
        if(check==2){
            /**
             * 直接转移绑定
             */
            deviceService.bind(device.getId(),bd.getId(),Const.deviceStatus_2);
            /**
             * 解绑记录统计（用于首页撤机门店统计）
             */
            this.saveRecords(records,user);
            /**
             * 记录解绑，判定门店是否已无设备
             */
            ZoneId defaultZoneId = ZoneId.systemDefault();
            LocalDateTime dateTime = LocalDateTime.ofInstant(records.getCreateTime().toInstant(), defaultZoneId).plusDays(7);
            String unbindTime = dateTime.toString();
            String unbindDate = dateTime.toLocalDate().toString();
            this.saveEmptyShopRecords(shop.getId(),unbindTime,unbindDate);
        }else {
            records.setIsCheck(Const.isCheck_1);
            String businessId = String.format(Const.device_business_id_D,id);
            if(!deviceService.lock(device.getId(),businessId))throw new ChechDataAuthException("设备状态异常");
        }
        this.save(records);
    }

    /**
     * 绑定，设备由 BD->门店
     * 转出方为BD，接收方为门店
     * @param deviceInfoList
     * @param bd
     */
    public Result<?> bind(List<ApiAddShopEntity.DeviceInfo> deviceInfoList, YlShop shop, SysUser bd,String remark){

        for(ApiAddShopEntity.DeviceInfo devices:deviceInfoList){
            YlDeviceRecords records = new YlDeviceRecords();
            String id = NumberArithmeticUtils.getTimestamp();
            records.setId(id);
            String transferNumber = String.format("%s_%s",Const.transfer_number_BD,id);
            records.setTransferNumber(transferNumber);
            GroupUser groupUser = deviceService.getGroupUser(devices.getId());
            /**
             * 设备状态1仓库2BD
             */
            if(devices.getType()==Const.deviceStatus_1){
                YlWarehouse warehouse = warehouseService.getById(devices.getId());
                records.setTransferId(devices.getId());
                String houseName = String.format(" %s | %s","仓库",warehouse.getHouseName());
                records.setTransferName(houseName);
            }else if(devices.getType()==Const.deviceStatus_2){
                records.setTransferId(groupUser.getUserId());
                records.setTransferName(groupUser.getUserInfo());
            }
            records.setTransferTime(new Date());
            records.setTransferType(Const.transferType_4); //绑定门店
            String shopName = String.format(" %s | %s","门店",shop.getShopName());
            records.setReceiveName(shopName);
            records.setReceiveId(shop.getId());
            records.setDeviceId(devices.getDeviceId());
            records.setDeviceMac(devices.getMac());
            records.setCreateBy(groupUser.getUserInfo());
            records.setTransferStatus(Const.transferStatus_2);
            records.setTransferRemark(remark);
            boolean res = this.save(records);
            /**
             * 绑定设备
             */
            if(res)deviceService.bindShop(devices.getDeviceId(), shop.getId());
        }
        return Result.OK("提交成功！");
    }

    /**
     * 门店绑定设备
     * @param apiBindDevice
     * @param bd
     */
    public void bindDevice(ApiBindDevice apiBindDevice,YlShop shop, SysUser bd){
        bind(apiBindDevice.getDevice(),  shop,  bd,"主动绑定");
        /**
         * 增加判定逻辑，去掉无设备记录中的记录数据
         */
        this.deleteEmptyShop(shop.getId());
    }


    @Override
    public IPage<YlDeviceRecords> shopDeviceList(Page<YlDeviceRecords> pagge, String shopId) {
        return baseMapper.shopDeviceList(pagge, shopId);
    }

    /**
     * 统计门店下设备数量
     * @param shopId
     * @return
     */
    public int countShopDevice(String shopId){
        QueryWrapper<YlDevice> deviceQueryWrapper = new QueryWrapper<>();
        deviceQueryWrapper.eq("business_id",shopId);
        return deviceService.count(deviceQueryWrapper);
    }


    //endregion
    /**-----------------------------------------接口使用----------------------------------------------------------------------------------*/


    /**-----------------------------------------通用---------------------------------------------------------------------------------*/
    //region 通用方法

    /**
     * 拿到GroupUser 信息
     * @param userId
     * @return
     */
    public GroupUser getGroupUser(String userId){
        return deviceService.getGroupUser(userId);
    }

    /**
     * 解绑记录统计（用于首页撤机门店统计）
     * @param records
     * @param user
     */
    public void saveRecords(YlDeviceRecords records,GroupUser user){
        YlWeaningShopRecord weaningShopRecord = new YlWeaningShopRecord();
        weaningShopRecord.setUnbindTime(records.getCreateTime());
        weaningShopRecord.setGroupId(user.getGroupId());
        weaningShopRecord.setShopId(records.getTransferId());
        weaningShopRecord.setBdId(user.getUserId());
        weaningShopRecord.setShopName(records.getTransferName());
        weaningShopRecordService.addWeaningShopRecordApi(weaningShopRecord);
    }
    //endregion
    /**-----------------------------------------通用----------------------------------------------------------------------------------*/
}
